home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / SLAX 6.0.8 / slax-6.0.8.iso / slax / base / 006-devel.lzm / usr / include / mimelib / string.h < prev    next >
Encoding:
C/C++ Source or Header  |  2007-05-14  |  31.5 KB  |  773 lines

  1. //=============================================================================
  2. // File:       dwstring.h
  3. // Contents:   Declarations for DwString
  4. // Maintainer: Doug Sauder <dwsauder@fwb.gulf.net>
  5. // WWW:        http://www.fwb.gulf.net/~dwsauder/mimepp.html
  6. //
  7. // Copyright (c) 1996, 1997 Douglas W. Sauder
  8. // All rights reserved.
  9. //
  10. // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT,
  11. // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
  12. // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER
  13. // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14. //
  15. // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT
  16. // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  17. // PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
  18. // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
  19. // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20. //
  21. //=============================================================================
  22.  
  23. #ifndef DW_STRING_H
  24. #define DW_STRING_H
  25.  
  26. #include <assert.h>
  27. #include <stddef.h>
  28. #include <iostream>
  29. #include <stdio.h>
  30.  
  31. #ifndef DW_CONFIG_H
  32. #include <mimelib/config.h>
  33. #endif
  34.  
  35. #if defined(DW_USE_ANSI_STRING)
  36.  
  37. #include <string>
  38. typedef std::string DwString;
  39.  
  40. #else // ! defined(DW_USE_ANSI_STRING)
  41.  
  42. //=============================================================================
  43. // DwStringRep is an implementation class that should not be used externally.
  44. //=============================================================================
  45.  
  46. struct DW_EXPORT DwStringRep {
  47.     DwStringRep(char* aBuf, size_t aSize);
  48.     DwStringRep(FILE* aFile, size_t aSize);
  49.     ~DwStringRep();
  50.     // void* operator new(size_t);
  51.     // void operator delete(void*, size_t);
  52.     size_t mSize;
  53.     char* mBuffer;
  54.     int mRefCount, mPageMod;
  55. //private:
  56.     // memory management
  57.     // DwStringRep* mNext;
  58.     // static DwStringRep* theirPool;
  59.     // static int theirPoolCount;
  60. public:
  61.     void CheckInvariants() const;
  62. };
  63.  
  64.  
  65. //=============================================================================
  66. //+ Name DwString -- String class
  67. //+ Description
  68. //. {\tt DwString} is the workhorse of the MIME++ library.  Creating, parsing,
  69. //. or otherwise manipulating MIME messages is basically a matter of
  70. //. manipulating strings.  {\tt DwString} provides all the basic functionality
  71. //. required of a string object, including copying, comparing, concatenating,
  72. //. and so on.
  73. //.
  74. //. {\tt DwString} is similar to the {\tt string} class that is part of
  75. //. the proposed ANSI standard C++ library.  Some of the member functions
  76. //. present in the ANSI {\tt string} are not present in {\tt DwString}:
  77. //. mostly these are the functions that deal with iterators.  {\tt DwString}
  78. //. also includes some member functions and class utility functions that
  79. //. are not a part of the ANSI {\tt string} class.  These non-ANSI
  80. //. functions are easy to distinguish: they all begin with upper-case
  81. //. letters, and all ANSI functions begin with lower-case letters.  The
  82. //. library classes themselves use only the ANSI {\tt string} functions.
  83. //. At some point in the future, MIME++ will probably allow the option to
  84. //. substitute the ANSI {\tt string} class for {\tt DwString}.
  85. //.
  86. //. {\tt DwString} makes extensive use of copy-on-write, even when extracting
  87. //. substrings.  It is this feature that distiguishes {\tt DwString} from most
  88. //. other string classes.  {\tt DwString} also handles binary data, which can
  89. //. contain embedded NUL characters.
  90. //=============================================================================
  91. //+ Noentry _copy _replace Length AsCharBuf Substring Prefix Suffix Prepend
  92. //+ Noentry Append Insert Replace Delete mRep mStart mLength sEmptyString
  93. //+ Noentry ~DwString
  94.  
  95.  
  96. class DW_EXPORT DwString {
  97.  
  98. public:
  99.  
  100.     static const size_t npos;
  101.     //. {\tt npos} is assigned the value (size_t)-1.
  102.  
  103.     DwString();
  104.     DwString(const DwString& aStr, size_t aPos=0, size_t aLen=npos);
  105.     DwString(const char* aBuf, size_t aLen);
  106.     DwString(FILE* aFile , size_t aLen);
  107.     DwString(const char* aCstr);
  108.     DwString(size_t aLen, char aChar);
  109.     DwString(char* aBuf, size_t aSize, size_t aStart, size_t aLen);
  110.     //. The first constructor is the default constructor, which sets the
  111.     //. {\tt DwString} object's contents to be empty.
  112.     //.
  113.     //. The second constructor is the copy constructor, which copies at most
  114.     //. {\tt aLen} characters beginning at position
  115.     //. {\tt aPos} from {\tt aStr} to the new {\tt DwString} object.  It will
  116.     //. not copy more characters than what are available in {\tt aStr}.
  117.     //. {\tt aPos} must be less than or equal to {\tt aStr.size()}.
  118.     //.
  119.     //. The third constructor copies {\tt aLen} characters from the buffer
  120.     //. {\tt aBuf} into the new {\tt DwString} object. {\tt aBuf} need not be
  121.     //. NUL-terminated and may contain NUL characters.
  122.     //.
  123.     //. The fourth constructor copies the contents of the NUL-terminated string
  124.     //. {\tt aCstr} into the new {\tt DwString} object.
  125.     //.
  126.     //. The fifth constructor sets the contents of the new {\tt DwString}
  127.     //. object to be the character {\tt aChar} repeated {\tt aLen} times.
  128.     //.
  129.     //. The sixth constructor is an {\it advanced} constructor that sets
  130.     //. the contents of the new {\tt DwString} object to the {\tt aLen}
  131.     //. characters starting at offset {\tt aStart} in the buffer {\tt aBuf}.
  132.     //. {\tt aSize} is the allocated size of {\tt aBuf}.
  133.     //. This constructor is provided for efficiency in setting a new
  134.     //. {\tt DwString}'s contents from a large buffer.  It is efficient
  135.     //. because no copying takes place.  Instead, {\tt aBuf} becomes the
  136.     //. buffer used internally by the {\tt DwString} object, which
  137.     //. takes responsibility for deleting the buffer.
  138.     //. Because {\tt DwString} will free the buffer using {\tt delete []},
  139.     //. the buffer should have been allocated using {\tt new}.
  140.     //. See also: TakeBuffer(), and ReleaseBuffer().
  141.  
  142.     virtual ~DwString();
  143.  
  144.     DwString& operator = (const DwString& aStr);
  145.     DwString& operator = (const char* aCstr);
  146.     DwString& operator = (char aChar);
  147.     //. Assigns the contents of the operand to this string.
  148.     //. {\tt aCstr} must point to a NUL-terminated array of characters
  149.     //. (a C string).
  150.     //. Returns {\tt *this}.
  151.  
  152.     size_t size() const;
  153.     //. Returns the number of characters in this string's contents.  This
  154.     //. member function is identical to {\tt length()}
  155.  
  156.     size_t length() const;
  157.     //. Returns the number of characters in this string's contents.  This
  158.     //. member function is identical to {\tt size()}
  159.  
  160.     size_t max_size() const;
  161.     //. Returns the maximum length that this string can ever attain.
  162.  
  163.     void resize(size_t aLen, char aChar);
  164.     void resize(size_t aLen);
  165.     //. Changes the length of this string. If the string shortened, the final
  166.     //. characters are truncated. If the string is expanded, the added
  167.     //. characters will be NULs or the character specified by {\tt aChar}.
  168.  
  169.     size_t capacity() const;
  170.     //. Returns the size of the internal buffer used for this string, which
  171.     //. will always be greater than or equal to the length of the string.
  172.  
  173.     void reserve(size_t aSize);
  174.     //. If {\tt aSize} is greater than the current capacity of this string,
  175.     //. this member function will increase the capacity to be at least
  176.     //. {\tt aSize}.
  177.  
  178.     void clear();
  179.     //. Sets this string's contents to be empty.
  180.  
  181.     DwBool empty() const;
  182.     //. Returns a true value if and only if the contents of this string
  183.     //. are empty.
  184.  
  185.     const char& operator [] (size_t aPos) const;
  186.     char& operator [] (size_t aPos);
  187.     //. Returns {\tt DwString::at(aPos) const} or {\tt DwString::at(aPos)}.
  188.     //. Note that the non-const version always assumes that the contents
  189.     //. will be modified and therefore always copies a shared internal
  190.     //. buffer before it returns.
  191.  
  192.     const char& at(size_t aPos) const;
  193.     char& at(size_t aPos);
  194.     //. Returns the character at position {\tt aPos} in the string's contents.
  195.     //. The non-const version returns an lvalue that may be assigned to.
  196.     //. Note that the non-const version always assumes that the contents
  197.     //. will be modified and therefore always copies a shared internal
  198.     //. buffer before it returns.
  199.  
  200.     DwString& operator += (const DwString& aStr);
  201.     DwString& operator += (const char* aCstr);
  202.     DwString& operator += (char aChar);
  203.     //. Appends the contents of the operand to this string.
  204.     //. {\tt aCstr} must point to a NUL-terminated array of characters
  205.     //. (a C string).
  206.     //. Returns {\tt *this}.
  207.  
  208.     DwString& append(const DwString& aStr);
  209.     DwString& append(const DwString& aStr, size_t aPos, size_t aLen);
  210.     DwString& append(const char* aBuf, size_t aLen);
  211.     DwString& append(const char* aCstr);
  212.     DwString& append(size_t aLen, char aChar);
  213.     //. Appends characters to (the end of) this string.
  214.     //. Returns {\tt *this}.
  215.     //.
  216.     //. The first version appends all of the characters from {\tt aStr}.
  217.     //.
  218.     //. The second version appends at most {\tt aLen} characters from
  219.     //. {\tt aStr} beginning at position {\tt aPos}.  {\tt aPos} must be
  220.     //. less than or equal to {\tt aStr.size()}.  The function will not
  221.     //. append more characters than what are available in {\tt aStr}.
  222.     //.
  223.     //. The third version appends {\tt aLen} characters from {\tt aBuf},
  224.     //. which is not assumed to be NUL-terminated and can contain embedded
  225.     //. NULs.
  226.     //.
  227.     //. The fourth version appends characters from the NUL-terminated
  228.     //. string {\tt aCstr}.
  229.     //.
  230.     //. The fifth version appends {\tt aChar} repeated {\tt aLen} times.
  231.  
  232.     DwString& assign(const DwString& aStr);
  233.     DwString& assign(const DwString& aStr, size_t aPos, size_t aLen);
  234.     DwString& assign(const char* aBuf, size_t aLen);
  235.     DwString& assign(const char* aCstr);
  236.     DwString& assign(size_t aLen, char aChar);
  237.     //. Assigns characters to this string.
  238.     //. Returns {\tt *this}.
  239.     //.
  240.     //. The first version assigns all of the characters from {\tt aStr}.
  241.     //.
  242.     //. The second version assigns at most {\tt aLen} characters from
  243.     //. {\tt aStr} beginning at position {\tt aPos}.  {\tt aPos} must be
  244.     //. less than or equal to {\tt aStr.size()}.  The function will not
  245.     //. assign more characters than what are available in {\tt aStr}.
  246.     //.
  247.     //. The third version assigns {\tt aLen} characters from {\tt aBuf},
  248.     //. which is not assumed to be NUL-terminated and can contain embedded
  249.     //. NULs.
  250.     //.
  251.     //. The fourth version assigns characters from the NUL-terminated
  252.     //. string {\tt aCstr}.
  253.     //.
  254.     //. The fifth version assigns {\tt aChar} repeated {\tt aLen} times.
  255.  
  256.     DwString& insert(size_t aPos1, const DwString& aStr);
  257.     DwString& insert(size_t aPos1, const DwString& aStr, size_t aPos2,
  258.         size_t aLen2);
  259.     DwString& insert(size_t aPos1, const char* aBuf, size_t aLen2);
  260.     DwString& insert(size_t aPos1, const char* aCstr);
  261.     DwString& insert(size_t aPos1, size_t aLen2, char aChar);
  262.     //. Inserts characters into this string beginning at position {\tt aPos1}.
  263.     //. Returns {\tt *this}.
  264.     //.
  265.     //. The first version inserts all of the characters from {\tt aStr}.
  266.     //.
  267.     //. The second version inserts at most {\tt aLen2} characters from
  268.     //. {\tt aStr} beginning at position {\tt aPos2}.  {\tt aPos1} must be
  269.     //. less than or equal to {\tt aStr.size()}.  The function will not
  270.     //. assign more characters than what are available in {\tt aStr}.
  271.     //.
  272.     //. The third version inserts {\tt aLen2} characters from {\tt aBuf},
  273.     //. which is not assumed to be NUL-terminated and can contain embedded
  274.     //. NULs.
  275.     //.
  276.     //. The fourth version inserts characters from the NUL-terminated
  277.     //. string {\tt aCstr}.
  278.     //.
  279.     //. The fifth version inserts {\tt aChar} repeated {\tt aLen2} times.
  280.  
  281.     DwString& erase(size_t aPos=0, size_t aLen=npos);
  282.     //. Erases (removes) at most {\tt aLen} characters beginning at position
  283.     //. {\tt aPos} from this string.
  284.     //. The function will not erase more characters than what are
  285.     //. available.
  286.     //. Returns {\tt *this}.
  287.  
  288.     DwString& replace(size_t aPos1, size_t aLen1, const DwString& aStr);
  289.     DwString& replace(size_t aPos1, size_t aLen1, const DwString& aStr,
  290.         size_t aPos2, size_t aLen2);
  291.     DwString& replace(size_t aPos1, size_t aLen1, const char* aBuf,
  292.         size_t aLen2);
  293.     DwString& replace(size_t aPos1, size_t aLen1, const char* aCstr);
  294.     DwString& replace(size_t aPos1, size_t aLen1, size_t aLen2, char aChar);
  295.     //. Removes {\tt aLen1} characters beginning at position {\tt aPos1}
  296.     //. and inserts other characters.
  297.     //. Returns {\tt *this}.
  298.     //.
  299.     //. The first version inserts all of the characters from {\tt aStr}.
  300.     //.
  301.     //. The second version inserts at most {\tt aLen2} characters from
  302.     //. {\tt aStr} beginning at position {\tt aPos2}.  {\tt aPos1} must be
  303.     //. less than or equal to {\tt aStr.size()}.  The function will not
  304.     //. assign more characters than what are available in {\tt aStr}.
  305.     //.
  306.     //. The third version inserts {\tt aLen2} characters from {\tt aBuf},
  307.     //. which is not assumed to be NUL-terminated and can contain embedded
  308.     //. NULs.
  309.     //.
  310.     //. The fourth version inserts characters from the NUL-terminated
  311.     //. string {\tt aCstr}.
  312.     //.
  313.     //. The fifth version inserts {\tt aChar} repeated {\tt aLen2} times.
  314.  
  315.     size_t copy(char* aBuf, size_t aLen, size_t aPos=0) const;
  316.     //. Copies at most {\tt aLen} characters beginning at position {\tt aPos}
  317.     //. from this string to the buffer pointed to by {\tt aBuf}.
  318.     //. Returns the number of characters copied.
  319.  
  320.     void swap(DwString& aStr);
  321.     //. Swaps the contents of this string and {\tt aStr}.
  322.  
  323.     const char* c_str() const;
  324.     const char* data() const;
  325.     //. These member functions permit access to the internal buffer used
  326.     //. by the {\tt DwString} object.  {\tt c_str()} returns a NUL-terminated
  327.     //. string suitable for use in C library functions.  {\tt data()}
  328.     //. returns a pointer to the internal buffer, which may not be
  329.     //. NUL-terminated.
  330.     //.
  331.     //. {\tt c_str()} may copy the internal buffer in order to place the
  332.     //. terminating NUL.  This is not a violation of the const declaration:
  333.     //. it is a logical const, not a bit-representation const.  It could
  334.     //. have the side effect of invalidating a pointer previously returned
  335.     //. by {\tt c_str()} or {\tt data()}.
  336.     //.
  337.     //. The characters in the returned string should not be modified, and
  338.     //. should be considered invalid after any call to a non-const member
  339.     //. function or another call to {\tt c_str()}.
  340.  
  341.     size_t find(const DwString& aStr, size_t aPos=0) const;
  342.     size_t find(const char* aBuf, size_t aPos, size_t aLen) const;
  343.     size_t find(const char* aCstr, size_t aPos=0) const;
  344.     size_t find(char aChar, size_t aPos=0) const;
  345.     //. Performs a forward search for a sequence of characters in the
  346.     //. {\tt DwString} object.  The return value is the position of the
  347.     //. sequence in the string if found, or {\tt DwString::npos} if not
  348.     //. found.
  349.     //.
  350.     //. The first version searches beginning at position {\tt aPos} for
  351.     //. the sequence of characters in {\tt aStr}.
  352.     //.
  353.     //. The second version searches beginning at position {\tt aPos} for
  354.     //. the sequence of {\tt aLen} characters in {\tt aBuf}, which need not
  355.     //. be NUL-terminated and can contain embedded NULs.
  356.     //.
  357.     //. The third version searches beginning at position {\tt aPos} for
  358.     //. the sequence of characters in the NUL-terminated string {\tt aCstr}.
  359.     //.
  360.     //. The fourth version searches beginning at position {\tt aPos} for
  361.     //. the character {\tt aChar}.
  362.  
  363.     size_t rfind(const DwString& aStr, size_t aPos=npos) const;
  364.     size_t rfind(const char* aBuf, size_t aPos, size_t aLen) const;
  365.     size_t rfind(const char* aCstr, size_t aPos=npos) const;
  366.     size_t rfind(char aChar, size_t aPos=npos) const;
  367.     //. Performs a reverse search for a sequence of characters in the
  368.     //. {\tt DwString} object.  The return value is the position of the
  369.     //. sequence in the string if found, or {\tt DwString::npos} if not
  370.     //. found.
  371.     //.
  372.     //. The first version searches beginning at position {\tt aPos} for
  373.     //. the sequence of characters in {\tt aStr}.
  374.     //.
  375.     //. The second version searches beginning at position {\tt aPos} for
  376.     //. the sequence of {\tt aLen} characters in {\tt aBuf}, which need not
  377.     //. be NUL-terminated and can contain embedded NULs.
  378.     //.
  379.     //. The third version searches beginning at position {\tt aPos} for
  380.     //. the sequence of characters in the NUL-terminated string {\tt aCstr}.
  381.     //.
  382.     //. The fourth version searches beginning at position {\tt aPos} for
  383.     //. the character {\tt aChar}.
  384.  
  385.     size_t find_first_of(const DwString& aStr, size_t aPos=0) const;
  386.     size_t find_first_of(const char* aBuf, size_t aPos, size_t aLen) const;
  387.     size_t find_first_of(const char* aCstr, size_t aPos=0) const;
  388.     //. Performs a forward search beginning at position {\tt aPos} for
  389.     //. the first occurrence of any character from a specified set of
  390.     //. characters.  The return value is the position of the character
  391.     //. if found, or {\tt DwString::npos} if not found.
  392.     //.
  393.     //. The first version searches for any character in the string {\tt aStr}.
  394.     //.
  395.     //. The second version searches for any of the {\tt aLen} characters in
  396.     //. {\tt aBuf}.
  397.     //.
  398.     //. The third version searches for any character in the NUL-terminated
  399.     //. string {\tt aCstr}.
  400.  
  401.     size_t find_last_of(const DwString& aStr, size_t aPos=npos) const;
  402.     size_t find_last_of(const char* aBuf, size_t aPos, size_t aLen) const;
  403.     size_t find_last_of(const char* aCstr, size_t aPos=npos) const;
  404.     //. Performs a reverse search beginning at position {\tt aPos} for
  405.     //. the first occurrence of any character from a specified set of
  406.     //. characters.  If {\tt aPos} is greater than or equal to the number
  407.     //. of characters in the string, then the search starts at the end
  408.     //. of the string.  The return value is the position of the character
  409.     //. if found, or {\tt DwString::npos} if not found.
  410.     //.
  411.     //. The first version searches for any character in the string {\tt aStr}.
  412.     //.
  413.     //. The second version searches for any of the {\tt aLen} characters in
  414.     //. {\tt aBuf}.
  415.     //.
  416.     //. The third version searches for any character in the NUL-terminated
  417.     //. string {\tt aCstr}.
  418.  
  419.     size_t find_first_not_of(const DwString& aStr, size_t aPos=0) const;
  420.     size_t find_first_not_of(const char* aBuf, size_t aPos, size_t aLen) const;
  421.     size_t find_first_not_of(const char* aCstr, size_t aPos=0) const;
  422.     //. Performs a forward search beginning at position {\tt aPos} for
  423.     //. the first occurrence of any character {\it not} in a specified set
  424.     //. of characters.  The return value is the position of the character
  425.     //. if found, or {\tt DwString::npos} if not found.
  426.     //.
  427.     //. The first version searches for any character not in the string
  428.     //. {\tt aStr}.
  429.     //.
  430.     //. The second version searches for any character not among the
  431.     //. {\tt aLen} characters in {\tt aBuf}.
  432.     //.
  433.     //. The third version searches for any character not in the NUL-terminated
  434.     //. string {\tt aCstr}.
  435.  
  436.     size_t find_last_not_of(const DwString& aStr, size_t aPos=npos) const;
  437.     size_t find_last_not_of(const char* aBuf, size_t aPos, size_t aLen) const;
  438.     size_t find_last_not_of(const char* aCstr, size_t aPos=npos) const;
  439.     //. Performs a reverse search beginning at position {\tt aPos} for
  440.     //. the first occurrence of any character {\it not} in a specified set
  441.     //. of characters.  If {\tt aPos} is greater than or equal to the number
  442.     //. of characters in the string, then the search starts at the end
  443.     //. of the string.  The return value is the position of the character
  444.     //. if found, or {\tt DwString::npos} if not found.
  445.     //.
  446.     //. The first version searches for any character not in the string
  447.     //. {\tt aStr}.
  448.     //.
  449.     //. The second version searches for any character not among the
  450.     //. {\tt aLen} characters in {\tt aBuf}.
  451.     //.
  452.     //. The third version searches for any character not in the NUL-terminated
  453.     //. string {\tt aCstr}.
  454.  
  455.     DwString substr(size_t aPos=0, size_t aLen=npos) const;
  456.     //. Returns a string that contains at most {\tt aLen} characters from
  457.     //. the {\tt DwString} object beginning at position {\tt aPos}.  The
  458.     //. returned substring will not contain more characters than what are
  459.     //. available in the superstring {\tt DwString} object.
  460.  
  461.     int compare(const DwString& aStr) const;
  462.     int compare(size_t aPos1, size_t aLen1, const DwString& aStr) const;
  463.     int compare(size_t aPos1, size_t aLen1, const DwString& aStr,
  464.         size_t aPos2, size_t aLen2) const;
  465.     int compare(const char* aCstr) const;
  466.     int compare(size_t aPos1, size_t aLen1, const char* aBuf,
  467.         size_t aLen2=npos) const;
  468.     //. These member functions compare a sequence of characters to this
  469.     //. {\tt DwString} object, or a segment of this {\tt DwString} object.
  470.     //. They return -1, 0, or 1, depending on whether this {\tt DwString}
  471.     //. object is less than, equal to, or greater than the compared sequence
  472.     //. of characters, respectively.
  473.     //.
  474.     //. The first version compares {\tt aStr} to this string.
  475.     //.
  476.     //. The second version compares {\tt aStr} with the {\tt aLen1} characters
  477.     //. beginning at position {\tt aPos1} in this {\tt DwString} object.
  478.     //.
  479.     //. The third version compares the {tt aLen2} characters beginning at
  480.     //. position {\tt aPos2} in {\tt aStr} with the {\tt aLen1} characters
  481.     //. beginning at position {\tt aPos1} in this {\tt DwString} object.
  482.     //.
  483.     //. The fourth version compares the NUL-terminated string {\tt aCstr}
  484.     //. to this {\tt DwString}.
  485.     //.
  486.     //. The fifth version compares the {\tt aLen2} characters in {\tt aBuf}
  487.     //. with the {\tt aLen1} characters beginning at position {\tt aPos1} in
  488.     //. this {\tt DwString} object.
  489.  
  490.     // Non-ANSI member functions
  491.  
  492.     virtual const char* ClassName() const;
  493.     //. This virtual function returns the name of the class as a NUL-terminated
  494.     //. char string.
  495.  
  496.     int ObjectId() const;
  497.     //. Returns the unique object id for this {\tt DwString}.
  498.  
  499.     void ConvertToLowerCase();
  500.     void ConvertToUpperCase();
  501.     //. Converts this {\tt DwString} object's characters to all lower case or
  502.     //. all upper case.
  503.  
  504.     void Trim();
  505.     //. Removes all white space from the beginning and the end of this
  506.     //. {\tt DwString} object.  White space characters include ASCII HT,
  507.     //. LF, and SPACE.
  508.  
  509.     void WriteTo(std::ostream& aStrm) const;
  510.     //. Writes the contents of this {\tt DwString} object to the stream
  511.     //. {\tt aStrm}.
  512.  
  513.     int RefCount() const;
  514.     //. This {\it advanced} member function returns the number of
  515.     //. references to the internal buffer used by the {\tt DwString} object.
  516.  
  517.     void TakeBuffer(char* aBuf, size_t aSize, size_t aStart, size_t aLen);
  518.     //. This {\it advanced} member function sets the contents of the
  519.     //. {\tt DwString} object to the {\tt aLen} characters starting at
  520.     //. offset {\tt aStart} in the buffer {\tt aBuf}.  {\tt aSize} is
  521.     //. the allocated size of {\tt aBuf}.
  522.     //. This member function is provided for efficiency in setting a
  523.     //. {\tt DwString}'s contents from a large buffer.  It is efficient
  524.     //. because no copying takes place.  Instead, {\tt aBuf} becomes the
  525.     //. buffer used internally by the {\tt DwString} object, which
  526.     //. takes responsibility for deleting the buffer.
  527.     //. Because DwString will free the buffer using {\tt delete []}, the
  528.     //. buffer should have been allocated using {\tt new}.
  529.     //. See also: ReleaseBuffer().
  530.  
  531.     void ReleaseBuffer(char** aBuf, size_t* aSize, size_t* aStart, size_t* aLen);
  532.     //. This {\it advanced} member function is the symmetric opposite of
  533.     //. {\tt TakeBuffer()}, to the extent that such an opposite is possible.
  534.     //. It provides a way to ``export'' the buffer used internally by the
  535.     //. {\tt DwString} object.
  536.     //. Note, however, that because of the copy-on-modify feature of
  537.     //. {\tt DwString}, the {\tt DwString} object may not have sole
  538.     //. ownership of its internal buffer.  When that is case,
  539.     //. {\tt ReleaseBuffer()} will return a copy of the buffer.  You can check
  540.     //. to see if the internal buffer is shared by calling {\tt RefCount()}.
  541.     //. On return from this member function, the {\tt DwString} object will
  542.     //. have valid, but empty, contents.
  543.     //. It is recommended that you use this function only on rare occasions
  544.     //. where you need to export efficiently a large buffer.
  545.  
  546.     void CopyTo(DwString* aStr) const;
  547.     //. This {\it advanced} member function copies this {\tt DwString}
  548.     //. object to {\tt aStr}.  This member
  549.     //. function is different from the assignment operator, because it
  550.     //. physically copies the buffer instead of just duplicating a reference
  551.     //. to it.
  552.  
  553. protected:
  554.  
  555.     DwStringRep* mRep;
  556.     size_t  mStart;
  557.     size_t  mLength;
  558.  
  559.     void _copy();
  560.     void _replace(size_t aPos1, size_t aLen1, const char* aBuf, size_t aLen2);
  561.     void _replace(size_t aPos1, size_t aLen1, size_t aLen2, char aChar);
  562.  
  563. private:
  564.     static const size_t kEmptyBufferSize;
  565.     static char sEmptyBuffer[];
  566.     static DwStringRep* sEmptyRep;
  567.     friend void mem_free(char*);
  568.  
  569. public:
  570.  
  571.     virtual void PrintDebugInfo(std::ostream& aStrm) const;
  572.     //. Prints debugging information about the object to {\tt aStrm}.
  573.     //.
  574.     //. This member function is available only in the debug version of
  575.     //. the library.
  576.  
  577.     virtual void CheckInvariants() const;
  578.     //. Aborts if one of the invariants of the object fails.  Use this
  579.     //. member function to track down bugs.
  580.     //.
  581.     //. This member function is available only in the debug version of
  582.     //. the library.
  583.  
  584. };
  585.  
  586.  
  587. //---------------------------------------------------------------------------
  588. // inline functions
  589. //---------------------------------------------------------------------------
  590.  
  591. inline size_t DwString::size() const
  592. {
  593.     return mLength;
  594. }
  595.  
  596. inline size_t DwString::length() const
  597. {
  598.     return mLength;
  599. }
  600.  
  601. inline size_t DwString::capacity() const
  602. {
  603.     return mRep->mSize - 1;
  604. }
  605.  
  606. inline DwBool DwString::empty() const
  607. {
  608.     return mLength == 0;
  609. }
  610.  
  611. inline int DwString::RefCount() const
  612. {
  613.     return mRep->mRefCount;
  614. }
  615.  
  616. inline const char* DwString::c_str() const
  617. {
  618.     if (mRep->mRefCount > 1 && mRep != sEmptyRep) {
  619.         DwString* xthis = (DwString*) this;
  620.         xthis->_copy();
  621.     }
  622.     return &mRep->mBuffer[mStart];
  623. }
  624.  
  625. inline const char* DwString::data() const
  626. {
  627.     return &mRep->mBuffer[mStart];
  628. }
  629.  
  630. // Returning const char& instead of char will allow us to use DwString::at()
  631. // in the following way:
  632. //    if (&s.at(1) == ' ') { /* ... */ }
  633. inline const char& DwString::at(size_t aPos) const
  634. {
  635.     assert(aPos <= mLength);
  636.     if (aPos < mLength) {
  637.         return data()[aPos];
  638.     }
  639.     else if (aPos == mLength) {
  640.         return sEmptyRep->mBuffer[0];
  641.     }
  642.     else {
  643.         // This "undefined behavior"
  644.         // Normally, this will not occur.  The assert() macro will catch it,
  645.         // or at some point we may throw an exception.
  646.         return data()[0];
  647.     }
  648. }
  649.  
  650. inline char& DwString::at(size_t aPos)
  651. {
  652.     assert(aPos < mLength);
  653.     if (aPos < mLength) {
  654.         return (char&) c_str()[aPos];
  655.     }
  656.     else {
  657.         // This is "undefined behavior"
  658.         assert(0);
  659.         return (char&) c_str()[0];
  660.     }
  661. }
  662.  
  663. // Returning const char& instead of char will allow us to use operator[]
  664. // in the following way:
  665. //    if (&s[1] == ' ') { /* ... */ }
  666. inline const char& DwString::operator [] (size_t aPos) const
  667. {
  668.     return at(aPos);
  669. }
  670.  
  671. inline char& DwString::operator [] (size_t aPos)
  672. {
  673.     return at(aPos);
  674. }
  675.  
  676. inline DwString& DwString::operator = (const DwString& aStr)
  677. {
  678.     return assign(aStr);
  679. }
  680.  
  681. inline DwString& DwString::operator = (const char* aCstr)
  682. {
  683.     return assign(aCstr);
  684. }
  685.  
  686. inline DwString& DwString::operator = (char aChar)
  687. {
  688.     return assign(1, aChar);
  689. }
  690.  
  691. inline DwString& DwString::operator += (const DwString& aStr)
  692. {
  693.     return append(aStr);
  694. }
  695.  
  696. inline DwString& DwString::operator += (const char* aCstr)
  697. {
  698.     return append(aCstr);
  699. }
  700.  
  701. inline DwString& DwString::operator += (char aChar)
  702. {
  703.     return append(1, aChar);
  704. }
  705.  
  706. #endif // ! defined(DW_USE_ANSI_STRING)
  707.  
  708. DW_EXPORT DwString operator + (const DwString& aStr1, const DwString& aStr2);
  709. DW_EXPORT DwString operator + (const char* aCstr, const DwString& aStr2);
  710. DW_EXPORT DwString operator + (char aChar, const DwString& aStr2);
  711. DW_EXPORT DwString operator + (const DwString& aStr1, const char* aCstr);
  712. DW_EXPORT DwString operator + (const DwString& aStr1, char aChar);
  713.  
  714. DW_EXPORT DwBool operator == (const DwString& aStr1, const DwString& aStr2);
  715. DW_EXPORT DwBool operator == (const DwString& aStr1, const char* aCstr);
  716. DW_EXPORT DwBool operator == (const char* aCstr, const DwString& aStr2);
  717.  
  718. DW_EXPORT DwBool operator != (const DwString& aStr1, const DwString& aStr2);
  719. DW_EXPORT DwBool operator != (const DwString& aStr1, const char* aCstr);
  720. DW_EXPORT DwBool operator != (const char* aCstr, const DwString& aStr2);
  721.  
  722. DW_EXPORT DwBool operator < (const DwString& aStr1, const DwString& aStr2);
  723. DW_EXPORT DwBool operator < (const DwString& aStr1, const char* aCstr);
  724. DW_EXPORT DwBool operator < (const char* aCstr, const DwString& aStr2);
  725.  
  726. DW_EXPORT DwBool operator > (const DwString& aStr1, const DwString& aStr2);
  727. DW_EXPORT DwBool operator > (const DwString& aStr1, const char* aCstr);
  728. DW_EXPORT DwBool operator > (const char* aCstr, const DwString& aStr2);
  729.  
  730. DW_EXPORT DwBool operator <= (const DwString& aStr1, const DwString& aStr2);
  731. DW_EXPORT DwBool operator <= (const DwString& aStr1, const char* aCstr);
  732. DW_EXPORT DwBool operator <= (const char* aCstr, const DwString& aStr2);
  733.  
  734. DW_EXPORT DwBool operator >= (const DwString& aStr1, const DwString& aStr2);
  735. DW_EXPORT DwBool operator >= (const DwString& aStr1, const char* aCstr);
  736. DW_EXPORT DwBool operator >= (const char* aCstr, const DwString& aStr2);
  737.  
  738. DW_EXPORT std::ostream& operator << (std::ostream& aOstrm, const DwString& aStr);
  739. //. Writes the contents of {\tt aStr} to the stream {\tt aOstrm}.
  740.  
  741. DW_EXPORT std::istream& getline (std::istream& aIstrm, DwString& aStr, char aDelim);
  742. DW_EXPORT std::istream& getline (std::istream& aIstrm, DwString& aStr);
  743.  
  744. DW_EXPORT int DwStrcasecmp(const DwString& aStr1, const DwString& aStr2);
  745. DW_EXPORT int DwStrcasecmp(const DwString& aStr1, const char* aCstr);
  746. DW_EXPORT int DwStrcasecmp(const char* aCstr, const DwString& aStr2);
  747.  
  748. DW_EXPORT int DwStrncasecmp(const DwString& aStr1, const DwString& aStr2,
  749.     size_t aLen);
  750. DW_EXPORT int DwStrncasecmp(const DwString& aStr, const char* aCstr, size_t aLen);
  751. DW_EXPORT int DwStrncasecmp(const char* aCstr, const DwString& aStr, size_t aLen);
  752.  
  753. DW_EXPORT int DwStrcmp(const DwString& aStr1, const DwString& aStr2);
  754. DW_EXPORT int DwStrcmp(const DwString& aStr, const char* aCstr);
  755. DW_EXPORT int DwStrcmp(const char* aCstr, const DwString& aStr);
  756.  
  757. DW_EXPORT int DwStrncmp(const DwString& aStr1, const DwString& aStr2, size_t aLen);
  758. DW_EXPORT int DwStrncmp(const DwString& aStr, const char* aCstr, size_t aLen);
  759. DW_EXPORT int DwStrncmp(const char* aCstr, const DwString& aStr, size_t aLen);
  760.  
  761. DW_EXPORT void DwStrcpy(DwString& aStrDest, const DwString& aStrSrc);
  762. DW_EXPORT void DwStrcpy(DwString& aStrDest, const char* aCstrSrc);
  763. DW_EXPORT void DwStrcpy(char* aCstrDest, const DwString& aStrSrc);
  764.  
  765. DW_EXPORT void DwStrncpy(DwString& aStrDest, const DwString& aStrSrc, size_t aLen);
  766. DW_EXPORT void DwStrncpy(DwString& aStrDest, const char* aCstrSrc, size_t aLen);
  767. DW_EXPORT void DwStrncpy(char* aCstrDest, const DwString& aStrSrc, size_t aLen);
  768.  
  769. DW_EXPORT char* DwStrdup(const DwString& aStr);
  770.  
  771. #endif
  772.  
  773.